package com.share.tool.attack.demo;


import com.share.common.utils.SnowFlakeUtil;
import com.share.common.utils.ThreadUtil;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Executor;

public class SnowFlakeAttackMain {
    /* 12bit==1024*2*2=4096  假定为4k*/
    public static void main(String[] args) {
        Executor executorService = ThreadUtil.getExecutor();
        Set statset = new HashSet();
        int c = 0;
        while (c++ < 1000) {
            //定义常量
            final int threadNum = 400;/*总的线程数*/
            final int oneThreadAttackNum = 10;/*每个线程攻击次数*/

            //定义存放数据的容器
            Map<Integer, List<Long>> map = new Hashtable<>();/*保证线程安全*/
            CountDownLatch latch = new CountDownLatch(threadNum);
            CyclicBarrier cb = new CyclicBarrier(threadNum);
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < threadNum; i++) {
                final int threadId = i;
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        //初始化
                        List<Long> tmpList = new LinkedList<>();
                        map.put(threadId, tmpList);

                        try {
//                        Thread.sleep(700);
//                            System.out.println("第" + threadId + "个线程准备就绪!");
                            cb.await();
//                            System.out.println("第" + threadId + "个线程---开始竞争");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        /*每个线程访问的次数*/
                        int count = 0;
                        while (count++ < oneThreadAttackNum) {
                            tmpList.add(SnowFlakeUtil.nextVal());
                        }
                        latch.countDown();
                    }
                });
            }

            //阻塞主线程
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            long costTime = System.currentTimeMillis() - startTime;
//			System.out.println("耗时毫秒=" + costTime);

            List<Long> list = new LinkedList<>();
            map.values().forEach(e -> list.addAll(e));
            Set<Long> set = new HashSet<>(list);

            System.out.println("第" + c + "轮,list=" + list.size() + ",set=" + set.size());
            statset.add(list.size() == set.size());
        }

        System.out.println("执行1000次:");
        statset.forEach(e -> System.out.println(e));

        //线程池所在方法阻塞，强制结束线程池
        ThreadUtil.shutdown();
    }
}
